package top.codedance.iotp.server.net.handle.subhandle.controller.http.sync;

import com.alibaba.fastjson.JSONObject;
import top.codedance.iotp.common.constent.Command;
import top.codedance.iotp.common.entity.CommonEntity;
import top.codedance.iotp.server.ServerApplication;
import top.codedance.iotp.server.net.TcpServer;
import top.codedance.iotp.server.net.handle.exception.*;
import top.codedance.iotp.server.net.handle.subhandle.controller.AdapterController;
import top.codedance.iotp.server.net.session.Session;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

public class HttpCommandController extends AdapterController {
    @Override
    public String doSubHandler(JSONObject body) {
        try {
            if (!userVerification()) {
                return response403("No access");
            }
            String deviceId = body.getString("deviceId");
            JSONObject command = body.getJSONObject("command");
            Session session = TcpServer.sessionManager.getSessionByDeviceId(deviceId);
            if(session == null){
                throw new DeviceOfflineException();
            }
            if(session.getChannel() == null){
                throw new ChannelNotFoundException();
            }
            if(command == null){
                throw new ParamNotEmptyException();
            }
            List<String> methods = new ArrayList<>();
            methods.add("POST");
            methods.add("GET");
            methods.add("DELETE");
            methods.add("PUT");
            methods.add("HEAD");
            methods.add("OPTIONS");
            methods.add("PATCH");
            if(command.getString("method") == null || !methods.contains(command.getString("method").toUpperCase())){
                throw new ParamFormatErrorException();
            }
            List<String> protocols = new ArrayList<>();
            protocols.add("HTTP");
            protocols.add("HTTPS");
            if(command.getString("protocol") == null || !protocols.contains(command.getString("protocol").toUpperCase())){
                throw new ParamFormatErrorException();
            }
            if(command.getString("url") == null){
                throw new ParamFormatErrorException();
            }
            CommonEntity commonEntity2 = new CommonEntity(ServerApplication.getDataVersion());
            commonEntity2.setCommand(Command.HTTP_COMMAND);
            commonEntity2.setBody(command.toJSONString().getBytes(StandardCharsets.UTF_8));
            CommonEntity commonEntity = TcpServer.syncRequestService.sendSyncMsg(session.getChannel(), commonEntity2);
            byte[] b = commonEntity.getBody();
            if(b == null){
                b = "".getBytes(StandardCharsets.UTF_8);
            }
            String s = new String(b, StandardCharsets.UTF_8);
            try {
                JSONObject jsonObject = JSONObject.parseObject(s);
                return okResponse(jsonObject);
            }catch (Exception e){
                return okResponse(s);
            }
        } catch (DeviceOfflineException | ChannelNotFoundException ex){
            return response500("Device offline");
        } catch (ParamNotEmptyException e) {
            return response500("parameters is not empty.");
        } catch (ParamFormatErrorException e) {
            return response500("Param format error.");
        } catch (RequestClientTimeoutException e) {
            return response500("request client timeout.");
        }
    }
}
